﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RCTools
	{
	public class Container
		{
		public static void displayDictionary<T, U>(Dictionary<T, U> dictionary)
			{
			List<T> listKeys = dictionary.Keys.ToList();
			foreach(var key in listKeys)
				{
				System.Console.WriteLine(key + " = " + dictionary[key]);
				}
			}

		public static bool isAllKeysInList<T, U>(Dictionary<T, U> dictionary, List<T> list)
			{
			List<T> listKeys = dictionary.Keys.ToList();
			foreach(var key in listKeys)
				{
				if(!list.Contains(key))
					{
					return false;
					}
				}
			return true;
			}

		public static void displayTab<T>(T[] tab)
			{
			for(int i = 0 ; i < tab.Count() ; i++)
				{
				System.Console.WriteLine(tab[i]);
				}
			}

		public static void displayList<T>(List<T> list)
			{
			foreach(var item in list)
				{
				System.Console.WriteLine(item);
				}
			}

		public static void fillAllTab<T>(T[] tab, T n)
			{
			for(int i = 0 ; i < tab.Count() ; i++)
				{
				tab[i] = n;
				}
			}
		}

	public class Numbers
		{
		/// <summary>
		/// Cette méthode renvoie un nombre aléatoire entre a compris et b compris
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		public static Int32 getRandomInteger(Int32 a, Int32 b)
			{
			if(a > b)
				{
				Int32 tmp = a;
				a = b;
				b = tmp;
				}

			System.Threading.Thread.Sleep(10);
			Random r = new Random(DateTime.Now.Millisecond);
			return r.Next(a, b + 1);
			}

		/// <summary>
		/// Cette méthode retourne un tableau d'entiers différents les uns avec les autres.
		/// La taille est définie par max - min
		/// </summary>
		/// <param name="min"></param>
		/// <param name="max"></param>
		/// <returns></returns>
		public static Int32[] getRandomTabDifferentIntegers(Int32 min, Int32 max)
			{
			if(max < min)
				{
				Int32 tmp = min;
				min = max;
				max = tmp;
				}

			Int32[] tab = new Int32[max - min];

			for(int i = 0 ; i < tab.Length ; i++)
				{
				Int32 v = 0;
				do
					{
					v = RCTools.Numbers.getRandomInteger(min, max);
					}
				while(tab.Contains(v));
				tab[i] = v;
				}

			return tab;
			}

		public static Int32[] getRandomTabDifferentIntegers(Int32 size, Int32 min, Int32 max)
			{
			if(max < min)
				{
				Int32 tmp = min;
				min = max;
				max = tmp;
				}

			if(size > max - min) { size = max - min; }

			Int32[] tab = new Int32[size];

			for(int i = 0 ; i < tab.Length ; i++)
				{
				Int32 v = 0;
				do
					{
					v = RCTools.Numbers.getRandomInteger(min, max);
					}
				while(tab.Contains(v));
				tab[i] = v;
				}

			return tab;
			}

		/// <summary>
		/// Cette méthode permet de comparer deux flottant en utilisant un epsilon passé en paramètre.
		/// Les deux nombres à comparer sont soustraits entre eux. Le résultat est prix dans l'absolu.
		/// Ce dernier est ensuite arrondi à 14 chiffres après la virgule. Cela veut dire que si des nombres
		/// avec plus de 14 chiffres significatifs après la virgule sont traités ave cette méthode, l'égalité
		/// sera certainement faux.
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <param name="e"></param>
		/// <returns></returns>
		public static bool isEgal(double a, double b, double e)
			{
			return Math.Abs((decimal)a - (decimal)b) <= (decimal)e;
			}

		/// <summary>
		/// Cette méthode permet de comparer deux flottant en utilisant un epsilon passé en paramètre.
		/// Les deux nombres à comparer sont soustraits entre eux. Le résultat est prix dans l'absolu.
		/// Ce dernier est ensuite arrondi à 5 chiffres après la virgule. Cela veut dire que si des nombres
		/// avec plus de 5 chiffres significatifs après la virgule sont traités ave cette méthode, l'égalité
		/// sera certainement faux. Dans ce cas la version en double pourrait fonctionner.
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <param name="e"></param>
		/// <returns></returns>
		public static bool isEgal(float a, float b, float e)
			{
			return Math.Abs((decimal)a - (decimal)b) <= (decimal)e;
			}
		}
	}
